package backed.controller;

import backed.entity.EcoBehavior;
import backed.repository.BehaviorRepository;
import io.swagger.v3.oas.annotations.Operation;
import io.swagger.v3.oas.annotations.Parameter;
import io.swagger.v3.oas.annotations.tags.Tag;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;

import java.math.BigDecimal;
import java.time.LocalDate;
import java.time.format.DateTimeFormatter;
import java.util.*;
import java.util.stream.Collectors;

/**
 * 数据可视化控制器
 */
@Tag(name = "数据可视化", description = "提供数据可视化相关的接口")
@RestController
@CrossOrigin
@RequestMapping("/api/visualization")
public class VisualizationController {

    @Autowired
    private BehaviorRepository behaviorRepository;

    /**
     * 获取用户减碳量趋势数据
     * 根据指定的时间周期（周/月/年）获取用户的减碳量趋势数据
     */
    @Operation(summary = "减碳量趋势数据", description = "根据用户ID和时间周期获取减碳量趋势数据")
    @io.swagger.v3.oas.annotations.responses.ApiResponses({
        @io.swagger.v3.oas.annotations.responses.ApiResponse(responseCode = "200", description = "查询成功"),
        @io.swagger.v3.oas.annotations.responses.ApiResponse(responseCode = "400", description = "参数错误")
    })
    @GetMapping("/carbon-trends")
    public Object getCarbonTrends(
            @Parameter(description = "用户ID", required = true, example = "1")
            @RequestParam Long userId,
            
            @Parameter(description = "时间周期：week/month/year", required = true, example = "week")
            @RequestParam String period) {
        try {
            // 参数验证
            if (userId == null || userId <= 0) {
                return new HashMap<String, Object>() {{
                    put("success", false);
                    put("message", "用户ID无效");
                }};
            }

            // 验证period参数
            if (!Arrays.asList("week", "month", "year").contains(period)) {
                return new HashMap<String, Object>() {{
                    put("success", false);
                    put("message", "时间周期参数无效，支持的周期：week/month/year");
                }};
            }

            // 根据period计算起始日期和结束日期
            LocalDate endDate = LocalDate.now();
            LocalDate startDate;
            int dateFormatStyle;

            switch (period) {
                case "week":
                    startDate = endDate.minusDays(6); // 最近7天
                    dateFormatStyle = 0; // 日/月格式
                    break;
                case "month":
                    startDate = endDate.minusDays(29); // 最近30天
                    dateFormatStyle = 0; // 日/月格式
                    break;
                case "year":
                    startDate = endDate.minusDays(364); // 最近365天
                    dateFormatStyle = 1; // 月格式
                    break;
                default:
                    return new HashMap<String, Object>() {{
                        put("success", false);
                        put("message", "不支持的时间周期");
                    }};
            }

            // 查询用户在日期范围内的环保行为记录
            List<EcoBehavior> behaviors = behaviorRepository.findByUserIdAndRecordDateBetween(userId, startDate, endDate);

            // 按日期分组并计算每日减碳量
            Map<LocalDate, BigDecimal> dailyCarbonReduction = behaviors.stream()
                    .collect(Collectors.groupingBy(
                            EcoBehavior::getRecordDate,
                            Collectors.reducing(BigDecimal.ZERO, EcoBehavior::getCarbonReduction, BigDecimal::add)
                    ));

            // 生成完整的日期列表和对应的减碳量列表
            List<String> labels = new ArrayList<>();
            List<BigDecimal> values = new ArrayList<>();
            DateTimeFormatter formatter;

            // 根据不同周期设置日期格式化
            if (dateFormatStyle == 0) {
                formatter = DateTimeFormatter.ofPattern("MM/dd"); // 月/日格式
            } else {
                formatter = DateTimeFormatter.ofPattern("yyyy-MM"); // 年月格式
                // 对于年视图，按月分组
                Map<String, BigDecimal> monthlyCarbonReduction = new HashMap<>();
                for (LocalDate date = startDate; !date.isAfter(endDate); date = date.plusDays(1)) {
                    String monthKey = formatter.format(date);
                    BigDecimal reduction = dailyCarbonReduction.getOrDefault(date, BigDecimal.ZERO);
                    monthlyCarbonReduction.put(monthKey, monthlyCarbonReduction.getOrDefault(monthKey, BigDecimal.ZERO).add(reduction));
                }

                // 生成月份标签和值
                LocalDate monthDate = startDate.withDayOfMonth(1);
                while (!monthDate.isAfter(endDate)) {
                    String monthKey = formatter.format(monthDate);
                    labels.add(monthKey);
                    values.add(monthlyCarbonReduction.getOrDefault(monthKey, BigDecimal.ZERO));
                    monthDate = monthDate.plusMonths(1);
                }
                return new HashMap<String, Object>() {{
                    put("success", true);
                    put("data", new HashMap<String, Object>() {{
                        put("labels", labels);
                        put("values", values);
                    }});
                }};
            }

            // 对于周/月视图，按日显示
            for (LocalDate date = startDate; !date.isAfter(endDate); date = date.plusDays(1)) {
                labels.add(formatter.format(date));
                values.add(dailyCarbonReduction.getOrDefault(date, BigDecimal.ZERO));
            }

            // 构造返回数据
            return new HashMap<String, Object>() {{
                put("success", true);
                put("data", new HashMap<String, Object>() {{
                    put("labels", labels);
                    put("values", values);
                }});
            }};

        } catch (Exception e) {
            // 异常处理
            return new HashMap<String, Object>() {{
                put("success", false);
                put("message", "获取减碳量趋势数据失败：" + e.getMessage());
            }};
        }
    }
}